<!doctype html>
<html lang="en">
 <head> 
  <meta charset="UTF-8"> 
  <meta name="description" content="燎火的个人博客"> 
  <meta name="keyword" content="燎火,qq799378666,软件开发,java,c#,js,html,html5,css"> 
  <title>Java8新特性 - 流式数据处理</title> 
  <script src="/js/jquery-1.11.1.min.js"></script> 
  <script src="/js/bootstrap-3.3.5/js/bootstrap.js"></script> 
  <link href="/js/bootstrap-3.3.5/css/bootstrap.css" rel="stylesheet"> 
  <script src="/js/base.js"></script> 
  <script src="/js/nav.js"></script> 
  <script src="/js/jquery.toTop.min.js"></script> 
  <link href="/style/article.css" rel="stylesheet"> 
 </head> 
 <body> 
  <div id="main"> 
   <h3 id="title">Java8新特性 - 流式数据处理</h3> 
   <div id="content">
    <h4 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; font-weight: 500; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">一. 流式处理简介</strong></h4>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  在我接触到java8流式数据处理的时候，我的第一感觉是流式处理让集合操作变得简洁了许多，通常我们需要多行代码才能完成的操作，借助于流式处理可以在一行中实现。比如我们希望对一个包含整数的集合中筛选出所有的偶数，并将其封装成为一个新的List返回，那么在java8之前，我们需要通过如下代码实现：</p>
    <pre class="hljs php" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;Integer&gt;&nbsp;evens&nbsp;=&nbsp;new&nbsp;ArrayList&lt;&gt;();for&nbsp;(final&nbsp;Integer&nbsp;num&nbsp;:&nbsp;nums)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(num&nbsp;%&nbsp;2&nbsp;==&nbsp;0)&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;evens.add(num);
&nbsp;&nbsp;&nbsp;&nbsp;}
}</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">通过java8的流式处理，我们可以将代码简化为：</p>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;Integer&gt;&nbsp;evens&nbsp;=&nbsp;nums.stream().filter(num&nbsp;-&gt;&nbsp;num&nbsp;%&nbsp;2&nbsp;==&nbsp;0).collect(Collectors.toList());</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  先简单解释一下上面这行语句的含义，<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">stream()</code>操作将集合转换成一个流，<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">filter()</code>执行我们自定义的筛选处理，这里是通过lambda表达式筛选出所有偶数，最后我们通过<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">collect()</code>对结果进行封装处理，并通过<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Collectors.toList()</code>指定其封装成为一个List集合返回。<br>  由上面的例子可以看出，java8的流式处理极大的简化了对于集合的操作，实际上不光是集合，包括数组、文件等，只要是可以转换成流，我们都可以借助流式处理，类似于我们写SQL语句一样对其进行操作。java8通过内部迭代来实现对流的处理，一个流式处理可以分为三个部分：转换成流、中间操作、终端操作。如下图：<br><img src="https://static.oschina.net/uploads/img/201610/06140456_uXbM.png" alt="img" title="java8流式处理"><br>以集合为例，一个流式处理的操作我们首先需要调用<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">stream()</code>函数将其转换成流，然后再调用相应的<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">中间操作</code>达到我们需要对集合进行的操作，比如筛选、转换等，最后通过<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">终端操作</code>对前面的结果进行封装，返回我们需要的形式。</p>
    <h4 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; font-weight: 500; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">二. 中间操作</strong></h4>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">方便后面的例子演示，我们先定义一个简单的学生实体类：</p>
    <pre class="hljs cs" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">public&nbsp;class&nbsp;Student&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;学号&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;long&nbsp;id;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;name;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;int&nbsp;age;&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;年级&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;int&nbsp;grade;&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;专业&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;major;&nbsp;&nbsp;&nbsp;&nbsp;/**&nbsp;学校&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;String&nbsp;school;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;省略getter和setter}</pre>
    <pre class="hljs php" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">//&nbsp;初始化List&lt;Student&gt;&nbsp;students&nbsp;=&nbsp;new&nbsp;ArrayList&lt;Student&gt;()&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20160001,&nbsp;"孔明",&nbsp;20,&nbsp;1,&nbsp;"土木工程",&nbsp;"武汉大学"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20160002,&nbsp;"伯约",&nbsp;21,&nbsp;2,&nbsp;"信息安全",&nbsp;"武汉大学"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20160003,&nbsp;"玄德",&nbsp;22,&nbsp;3,&nbsp;"经济管理",&nbsp;"武汉大学"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20160004,&nbsp;"云长",&nbsp;21,&nbsp;2,&nbsp;"信息安全",&nbsp;"武汉大学"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20161001,&nbsp;"翼德",&nbsp;21,&nbsp;2,&nbsp;"机械与自动化",&nbsp;"华中科技大学"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20161002,&nbsp;"元直",&nbsp;23,&nbsp;4,&nbsp;"土木工程",&nbsp;"华中科技大学"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20161003,&nbsp;"奉孝",&nbsp;23,&nbsp;4,&nbsp;"计算机科学",&nbsp;"华中科技大学"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20162001,&nbsp;"仲谋",&nbsp;22,&nbsp;3,&nbsp;"土木工程",&nbsp;"浙江大学"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20162002,&nbsp;"鲁肃",&nbsp;23,&nbsp;4,&nbsp;"计算机科学",&nbsp;"浙江大学"));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;add(new&nbsp;Student(20163001,&nbsp;"丁奉",&nbsp;24,&nbsp;5,&nbsp;"土木工程",&nbsp;"南京大学"));
&nbsp;&nbsp;&nbsp;&nbsp;}
};</pre>
    <h5 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; font-size: 12px; font-weight: 500; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">2.1 过滤</strong></h5>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  过滤，顾名思义就是按照给定的要求对集合进行筛选满足条件的元素，java8提供的筛选操作包括：filter、distinct、limit、skip。</p>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>filter</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  在前面的例子中我们已经演示了如何使用filter，其定义为：<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Stream&lt;T&gt; filter(Predicate&lt;? super T&gt; predicate)</code>，filter接受一个谓词<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Predicate</code>，我们可以通过这个谓词定义筛选条件，在介绍lambda表达式时我们介绍过<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Predicate</code>是一个函数式接口，其包含一个<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">test(T t)</code>方法，该方法返回<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">boolean</code>。现在我们希望从集合<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">students</code>中筛选出所有武汉大学的学生，那么我们可以通过filter来实现，并将筛选操作作为参数传递给filter：</p>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;Student&gt;&nbsp;whuStudents&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"武汉大学".equals(student.getSchool()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());</pre>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>distinct</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  distinct操作类似于我们在写SQL语句时，添加的<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">DISTINCT</code>关键字，用于去重处理，distinct基于<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Object.equals(Object)</code>实现，回到最开始的例子，假设我们希望筛选出所有不重复的偶数，那么可以添加distinct操作：</p>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;Integer&gt;&nbsp;evens&nbsp;=&nbsp;nums.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(num&nbsp;-&gt;&nbsp;num&nbsp;%&nbsp;2&nbsp;==&nbsp;0).distinct()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());</pre>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>limit</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  limit操作也类似于SQL语句中的<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">LIMIT</code>关键字，不过相对功能较弱，limit返回包含前n个元素的流，当集合大小小于n时，则返回实际长度，比如下面的例子返回前两个专业为<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">土木工程</code>专业的学生：</p>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;Student&gt;&nbsp;civilStudents&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"土木工程".equals(student.getMajor())).limit(2)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  说到limit，不得不提及一下另外一个流操作：<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">sorted</code>。该操作用于对流中元素进行排序，sorted要求待比较的元素必须实现<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Comparable</code>接口，如果没有实现也不要紧，我们可以将比较器作为参数传递给<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">sorted(Comparator&lt;? super T&gt; comparator)</code>，比如我们希望筛选出专业为土木工程的学生，并按年龄从小到大排序，筛选出年龄最小的两个学生，那么可以实现为：</p>
    <pre class="hljs elixir" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;Student&gt;&nbsp;sortedCivilStudents&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"土木工程".equals(student.getMajor())).sorted((s1,&nbsp;s2)&nbsp;-&gt;&nbsp;s1.getAge()&nbsp;-&nbsp;s2.getAge())
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.limit(2)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());</pre>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>skip</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  skip操作与limit操作相反，如同其字面意思一样，是跳过前n个元素，比如我们希望找出排序在2之后的土木工程专业的学生，那么可以实现为：</p>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;Student&gt;&nbsp;civilStudents&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"土木工程".equals(student.getMajor()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.skip(2)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  通过skip，就会跳过前面两个元素，返回由后面所有元素构造的流，如果n大于满足条件的集合的长度，则会返回一个空的集合。</p>
    <h5 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; font-size: 12px; font-weight: 500; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">2.2 映射</strong></h5>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  在SQL中，借助<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">SELECT</code>关键字后面添加需要的字段名称，可以仅输出我们需要的字段数据，而流式处理的映射操作也是实现这一目的，在java8的流式处理中，主要包含两类映射操作：map和flatMap。</p>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>map</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  举例说明，假设我们希望筛选出所有专业为计算机科学的学生姓名，那么我们可以在filter筛选的基础之上，通过map将学生实体映射成为学生姓名字符串，具体实现如下：</p>
    <pre class="hljs rust" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;String&gt;&nbsp;names&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"计算机科学".equals(student.getMajor()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map(Student::getName).collect(Collectors.toList());</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  除了上面这类基础的map，java8还提供了<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">mapToDouble(ToDoubleFunction&lt;? super T&gt; mapper)</code>，<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">mapToInt(ToIntFunction&lt;? super T&gt; mapper)</code>，<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">mapToLong(ToLongFunction&lt;? super T&gt; mapper)</code>，这些映射分别返回对应类型的流，java8为这些流设定了一些特殊的操作，比如我们希望计算所有专业为计算机科学学生的年龄之和，那么我们可以实现如下：</p>
    <pre class="hljs rust" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">int&nbsp;totalAge&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"计算机科学".equals(student.getMajor()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.mapToInt(Student::getAge).sum();</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  通过将Student按照年龄直接映射为<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">IntStream</code>，我们可以直接调用提供的<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">sum()</code>方法来达到目的，此外使用这些数值流的好处还在于可以避免jvm装箱操作所带来的性能消耗。</p>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>flatMap</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  flatMap与map的区别在于&nbsp;<strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">flatMap是将一个流中的每个值都转成一个个流，然后再将这些流扁平化成为一个流</strong>&nbsp;。举例说明，假设我们有一个字符串数组<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">String[] strs = {"java8", "is", "easy", "to", "use"};</code>，我们希望输出构成这一数组的所有非重复字符，那么我们可能首先会想到如下实现：</p>
    <pre class="hljs rust" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;String[]&gt;&nbsp;distinctStrs&nbsp;=&nbsp;Arrays.stream(strs)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map(str&nbsp;-&gt;&nbsp;str.split(""))&nbsp;&nbsp;//&nbsp;映射成为Stream&lt;String[]&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.distinct()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  在执行map操作以后，我们得到是一个包含多个字符串（构成一个字符串的字符数组）的流，此时执行distinct操作是基于在这些字符串数组之间的对比，所以达不到我们希望的目的，此时的输出为：</p>
    <pre class="hljs json" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">[j,&nbsp;a,&nbsp;v,&nbsp;a,&nbsp;8]
[i,&nbsp;s]
[e,&nbsp;a,&nbsp;s,&nbsp;y]
[t,&nbsp;o]
[u,&nbsp;s,&nbsp;e]</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  distinct只有对于一个包含多个字符的流进行操作才能达到我们的目的，即对<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Stream&lt;String&gt;</code>进行操作。此时flatMap就可以达到我们的目的：</p>
    <pre class="hljs rust" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">List&lt;String&gt;&nbsp;distinctStrs&nbsp;=&nbsp;Arrays.stream(strs)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map(str&nbsp;-&gt;&nbsp;str.split(""))&nbsp;&nbsp;//&nbsp;映射成为Stream&lt;String[]&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.flatMap(Arrays::stream)&nbsp;&nbsp;//&nbsp;扁平化为Stream&lt;String&gt;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.distinct()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.collect(Collectors.toList());</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  flatMap将由map映射得到的<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Stream&lt;String[]&gt;</code>，转换成由各个字符串数组映射成的流<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Stream&lt;String&gt;</code>，再将这些小的流扁平化成为一个由所有字符串构成的大流<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Steam&lt;String&gt;</code>，从而能够达到我们的目的。<br>  与map类似，flatMap也提供了针对特定类型的映射操作：<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">flatMapToDouble(Function&lt;? super T,? extends DoubleStream&gt; mapper)</code>，<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">flatMapToInt(Function&lt;? super T,? extends IntStream&gt; mapper)</code>，<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">flatMapToLong(Function&lt;? super T,? extends LongStream&gt; mapper)</code>。</p>
    <h4 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; font-weight: 500; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">三. 终端操作</strong></h4>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  终端操作是流式处理的最后一步，我们可以在终端操作中实现对流查找、归约等操作。</p>
    <h5 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; font-size: 12px; font-weight: 500; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">3.1 查找</strong></h5>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>allMatch</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  allMatch用于检测是否全部都满足指定的参数行为，如果全部满足则返回true，例如我们希望检测是否所有的学生都已满18周岁，那么可以实现为：</p>
    <pre class="hljs elixir" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">boolean&nbsp;isAdult&nbsp;=&nbsp;students.stream().allMatch(student&nbsp;-&gt;&nbsp;student.getAge()&nbsp;&gt;=&nbsp;18);</pre>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>anyMatch</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  anyMatch则是检测是否存在一个或多个满足指定的参数行为，如果满足则返回true，例如我们希望检测是否有来自武汉大学的学生，那么可以实现为：</p>
    <pre class="hljs elixir" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">boolean&nbsp;hasWhu&nbsp;=&nbsp;students.stream().anyMatch(student&nbsp;-&gt;&nbsp;"武汉大学".equals(student.getSchool()));</pre>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>noneMatch</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  noneMatch用于检测是否不存在满足指定行为的元素，如果不存在则返回true，例如我们希望检测是否不存在专业为计算机科学的学生，可以实现如下：</p>
    <pre class="hljs nginx" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">boolean&nbsp;noneCs&nbsp;=&nbsp;students.stream().noneMatch(student&nbsp;-&gt;&nbsp;"计算机科学".equals(student.getMajor()));</pre>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>findFirst</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  findFirst用于返回满足条件的第一个元素，比如我们希望选出专业为土木工程的排在第一个学生，那么可以实现如下：</p>
    <pre class="hljs elixir" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">Optional&lt;Student&gt;&nbsp;optStu&nbsp;=&nbsp;students.stream().filter(student&nbsp;-&gt;&nbsp;"土木工程".equals(student.getMajor())).findFirst();</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  findFirst不携带参数，具体的查找条件可以通过filter设置，此外我们可以发现findFirst返回的是一个Optional类型，关于该类型的具体讲解可以参考上一篇：<a href="http://www.zhenchao.org/2016/09/24/java8-optional/" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border: none; outline: 0px; transition: color 0.3s; text-decoration: none; color: rgb(68, 102, 187);">Java8新特性 - Optional类</a>。</p>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>findAny</p></li>
    </ul>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  findAny相对于findFirst的区别在于，findAny不一定返回第一个，而是返回任意一个，比如我们希望返回任意一个专业为土木工程的学生，可以实现如下：</p>
    <pre class="hljs elixir" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">Optional&lt;Student&gt;&nbsp;optStu&nbsp;=&nbsp;students.stream().filter(student&nbsp;-&gt;&nbsp;"土木工程".equals(student.getMajor())).findAny();</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  实际上对于顺序流式处理而言，findFirst和findAny返回的结果是一样的，至于为什么会这样设计，是因为在下一篇我们介绍的&nbsp;<strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">并行流式处理</strong>，当我们启用并行流式处理的时候，查找第一个元素往往会有很多限制，如果不是特别需求，在并行流式处理中使用findAny的性能要比findFirst好。</p>
    <h5 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; font-size: 12px; font-weight: 500; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">3.2 归约</strong></h5>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  前面的例子中我们大部分都是通过<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">collect(Collectors.toList())</code>对数据封装返回，如我的目标不是返回一个新的集合，而是希望对经过参数化操作后的集合进行进一步的运算，那么我们可用对集合实施归约操作。java8的流式处理提供了<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">reduce</code>方法来达到这一目的。<br>  前面我们通过mapToInt将<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Stream&lt;Student&gt;</code>映射成为<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">IntStream</code>，并通过<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">IntStream</code>的sum方法求得所有学生的年龄之和，实际上我们通过归约操作，也可以达到这一目的，实现如下：</p>
    <pre class="hljs rust" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">//&nbsp;前面例子中的方法int&nbsp;totalAge&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"计算机科学".equals(student.getMajor()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.mapToInt(Student::getAge).sum();//&nbsp;归约操作int&nbsp;totalAge&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"计算机科学".equals(student.getMajor()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map(Student::getAge)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.reduce(0,&nbsp;(a,&nbsp;b)&nbsp;-&gt;&nbsp;a&nbsp;+&nbsp;b);//&nbsp;进一步简化int&nbsp;totalAge2&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"计算机科学".equals(student.getMajor()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map(Student::getAge)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.reduce(0,&nbsp;Integer::sum);//&nbsp;采用无初始值的重载版本，需要注意返回OptionalOptional&lt;Integer&gt;&nbsp;totalAge&nbsp;=&nbsp;students.stream()
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.filter(student&nbsp;-&gt;&nbsp;"计算机科学".equals(student.getMajor()))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.map(Student::getAge)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.reduce(Integer::sum);&nbsp;&nbsp;//&nbsp;去掉初始值</pre>
    <h5 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; font-size: 12px; font-weight: 500; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">3.3 收集</strong></h5>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  前面利用<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">collect(Collectors.toList())</code>是一个简单的收集操作，是对处理结果的封装，对应的还有<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">toSet</code>、<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">toMap</code>，以满足我们对于结果组织的需求。这些方法均来自于<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">java.util.stream.Collectors</code>，我们可以称之为收集器。</p>
    <h6 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">3.3.1 归约</strong></h6>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  收集器也提供了相应的归约操作，但是与reduce在内部实现上是有区别的，收集器更加适用于可变容器上的归约操作，这些收集器广义上均基于<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Collectors.reducing()</code>实现。</p>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>例1：求学生的总人数</p></li>
    </ul>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">long&nbsp;count&nbsp;=&nbsp;students.stream().collect(Collectors.counting());//&nbsp;进一步简化long&nbsp;count&nbsp;=&nbsp;students.stream().count();</pre>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>例2：求年龄的最大值和最小值</p></li>
    </ul>
    <pre class="hljs gradle" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">//&nbsp;求最大年龄Optional&lt;Student&gt;&nbsp;olderStudent&nbsp;=&nbsp;students.stream().collect(Collectors.maxBy((s1,&nbsp;s2)&nbsp;-&gt;&nbsp;s1.getAge()&nbsp;-&nbsp;s2.getAge()));//&nbsp;进一步简化Optional&lt;Student&gt;&nbsp;olderStudent2&nbsp;=&nbsp;students.stream().collect(Collectors.maxBy(Comparator.comparing(Student::getAge)));//&nbsp;求最小年龄Optional&lt;Student&gt;&nbsp;olderStudent3&nbsp;=&nbsp;students.stream().collect(Collectors.minBy(Comparator.comparing(Student::getAge)));</pre>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>例3：求年龄总和</p></li>
    </ul>
    <pre class="hljs groovy" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">int&nbsp;totalAge4&nbsp;=&nbsp;students.stream().collect(Collectors.summingInt(Student::getAge));</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">对应的还有<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">summingLong</code>、<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">summingDouble</code>。</p>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>例4：求年龄的平均值</p></li>
    </ul>
    <pre class="hljs groovy" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">double&nbsp;avgAge&nbsp;=&nbsp;students.stream().collect(Collectors.averagingInt(Student::getAge));</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">对应的还有<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">averagingLong</code>、<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">averagingDouble</code>。</p>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>例5：一次性得到元素个数、总和、均值、最大值、最小值</p></li>
    </ul>
    <pre class="hljs php" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">IntSummaryStatistics&nbsp;statistics&nbsp;=&nbsp;students.stream().collect(Collectors.summarizingInt(Student::getAge));</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">输出：</p>
    <pre class="hljs swift" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">IntSummaryStatistics{count=10,&nbsp;sum=220,&nbsp;min=20,&nbsp;average=22.000000,&nbsp;max=24}</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">对应的还有<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">summarizingLong</code>、<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">summarizingDouble</code>。</p>
    <ul style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-left: 30px; padding: 8px 15px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);" class=" list-paddingleft-2">
     <li><p>例6：字符串拼接</p></li>
    </ul>
    <pre class="hljs rust" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">String&nbsp;names&nbsp;=&nbsp;students.stream().map(Student::getName).collect(Collectors.joining());//&nbsp;输出：孔明伯约玄德云长翼德元直奉孝仲谋鲁肃丁奉String&nbsp;names&nbsp;=&nbsp;students.stream().map(Student::getName).collect(Collectors.joining(",&nbsp;"));//&nbsp;输出：孔明,&nbsp;伯约,&nbsp;玄德,&nbsp;云长,&nbsp;翼德,&nbsp;元直,&nbsp;奉孝,&nbsp;仲谋,&nbsp;鲁肃,&nbsp;丁奉</pre>
    <h6 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">3.3.2 分组</strong></h6>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  在数据库操作中，我们可以通过<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">GROUP BY</code>关键字对查询到的数据进行分组，java8的流式处理也为我们提供了这样的功能<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Collectors.groupingBy</code>来操作集合。比如我们可以按学校对上面的学生进行分组：</p>
    <pre class="hljs ruby" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">Map&lt;String,&nbsp;List&lt;Student&gt;&gt;&nbsp;groups&nbsp;=&nbsp;students.stream().collect(Collectors.groupingBy(Student::getSchool));</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  <code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">groupingBy</code>接收一个分类器<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Function&lt;? super T, ? extends K&gt; classifier</code>，我们可以自定义分类器来实现需要的分类效果。<br>  上面演示的是一级分组，我们还可以定义多个分类器实现&nbsp;<strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">多级分组</strong>，比如我们希望在按学校分组的基础之上再按照专业进行分组，实现如下：</p>
    <pre class="hljs javascript" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">Map&lt;String,&nbsp;Map&lt;String,&nbsp;List&lt;Student&gt;&gt;&gt;&nbsp;groups2&nbsp;=&nbsp;students.stream().collect(
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collectors.groupingBy(Student::getSchool,&nbsp;&nbsp;//&nbsp;一级分组，按学校
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Collectors.groupingBy(Student::getMajor)));&nbsp;&nbsp;//&nbsp;二级分组，按专业</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  实际上在<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">groupingBy</code>的第二个参数不是只能传递groupingBy，还可以传递任意<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Collector</code>类型，比如我们可以传递一个<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Collector.counting</code>，用以统计每个组的个数：</p>
    <pre class="hljs javascript" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">Map&lt;String,&nbsp;Long&gt;&nbsp;groups&nbsp;=&nbsp;students.stream().collect(Collectors.groupingBy(Student::getSchool,&nbsp;Collectors.counting()));</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">如果我们不添加第二个参数，则编译器会默认帮我们添加一个<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">Collectors.toList()</code>。</p>
    <h6 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">3.3.3 分区</strong></h6>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  分区可以看做是分组的一种特殊情况，在分区中key只有两种情况：true或false，目的是将待分区集合按照条件一分为二，java8的流式处理利用<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">ollectors.partitioningBy()</code>方法实现分区，该方法接收一个谓词，例如我们希望将学生分为武大学生和非武大学生，那么可以实现如下：</p>
    <pre class="hljs javascript" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">Map&lt;Boolean,&nbsp;List&lt;Student&gt;&gt;&nbsp;partition&nbsp;=&nbsp;students.stream().collect(Collectors.partitioningBy(student&nbsp;-&gt;&nbsp;"武汉大学".equals(student.getSchool())));</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  分区相对分组的优势在于，我们可以同时得到两类结果，在一些应用场景下可以一步得到我们需要的所有结果，比如将数组分为奇数和偶数。</p>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  以上介绍的所有收集器均实现自接口<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">java.util.stream.Collector</code>，该接口的定义如下：</p>
    <pre class="hljs php" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; overflow-x: auto; padding: 2px; background-color: rgb(63, 63, 63); color: rgb(220, 220, 220); border-radius: 3px; line-height: 1.4; word-wrap: normal; font-size: 13px; font-family: Menlo, Monaco, Consolas, &quot;Courier New&quot;, monospace;">public&nbsp;interface&nbsp;Collector&lt;T,&nbsp;A,&nbsp;R&gt;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;A&nbsp;function&nbsp;that&nbsp;creates&nbsp;and&nbsp;returns&nbsp;a&nbsp;new&nbsp;mutable&nbsp;result&nbsp;container.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;a&nbsp;function&nbsp;which&nbsp;returns&nbsp;a&nbsp;new,&nbsp;mutable&nbsp;result&nbsp;container
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;Supplier&lt;A&gt;&nbsp;supplier();&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;A&nbsp;function&nbsp;that&nbsp;folds&nbsp;a&nbsp;value&nbsp;into&nbsp;a&nbsp;mutable&nbsp;result&nbsp;container.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;a&nbsp;function&nbsp;which&nbsp;folds&nbsp;a&nbsp;value&nbsp;into&nbsp;a&nbsp;mutable&nbsp;result&nbsp;container
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;BiConsumer&lt;A,&nbsp;T&gt;&nbsp;accumulator();&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;A&nbsp;function&nbsp;that&nbsp;accepts&nbsp;two&nbsp;partial&nbsp;results&nbsp;and&nbsp;merges&nbsp;them.&nbsp;&nbsp;The
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;combiner&nbsp;function&nbsp;may&nbsp;fold&nbsp;state&nbsp;from&nbsp;one&nbsp;argument&nbsp;into&nbsp;the&nbsp;other&nbsp;and
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;return&nbsp;that,&nbsp;or&nbsp;may&nbsp;return&nbsp;a&nbsp;new&nbsp;result&nbsp;container.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;a&nbsp;function&nbsp;which&nbsp;combines&nbsp;two&nbsp;partial&nbsp;results&nbsp;into&nbsp;a&nbsp;combined
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;result
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;BinaryOperator&lt;A&gt;&nbsp;combiner();&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Perform&nbsp;the&nbsp;final&nbsp;transformation&nbsp;from&nbsp;the&nbsp;intermediate&nbsp;accumulation&nbsp;type
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;{@code&nbsp;A}&nbsp;to&nbsp;the&nbsp;final&nbsp;result&nbsp;type&nbsp;{@code&nbsp;R}.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;&lt;p&gt;If&nbsp;the&nbsp;characteristic&nbsp;{@code&nbsp;IDENTITY_TRANSFORM}&nbsp;is
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;set,&nbsp;this&nbsp;function&nbsp;may&nbsp;be&nbsp;presumed&nbsp;to&nbsp;be&nbsp;an&nbsp;identity&nbsp;transform&nbsp;with&nbsp;an
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;unchecked&nbsp;cast&nbsp;from&nbsp;{@code&nbsp;A}&nbsp;to&nbsp;{@code&nbsp;R}.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;a&nbsp;function&nbsp;which&nbsp;transforms&nbsp;the&nbsp;intermediate&nbsp;result&nbsp;to&nbsp;the&nbsp;final
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;result
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;Function&lt;A,&nbsp;R&gt;&nbsp;finisher();&nbsp;&nbsp;&nbsp;&nbsp;/**
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;Returns&nbsp;a&nbsp;{@code&nbsp;Set}&nbsp;of&nbsp;{@code&nbsp;Collector.Characteristics}&nbsp;indicating
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;the&nbsp;characteristics&nbsp;of&nbsp;this&nbsp;Collector.&nbsp;&nbsp;This&nbsp;set&nbsp;should&nbsp;be&nbsp;immutable.
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*&nbsp;@return&nbsp;an&nbsp;immutable&nbsp;set&nbsp;of&nbsp;collector&nbsp;characteristics
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*/
&nbsp;&nbsp;&nbsp;&nbsp;Set&lt;Characteristics&gt;&nbsp;characteristics();

}</pre>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  我们也可以实现该接口来定义自己的收集器，此处不再展开。</p>
    <h4 style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; font-weight: 500; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);"><strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">四. 并行流式数据处理</strong></h4>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">  流式处理中的很多都适合采用&nbsp;<strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">分而治之</strong>&nbsp;的思想，从而在处理集合较大时，极大的提高代码的性能，java8的设计者也看到了这一点，所以提供了&nbsp;<strong style="box-sizing: inherit; -webkit-tap-highlight-color: transparent;">并行流式处理</strong>。上面的例子中我们都是调用<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">stream()</code>方法来启动流式处理，java8还提供了<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">parallelStream()</code>来启动并行流式处理，<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">parallelStream()</code>本质上基于java7的Fork-Join框架实现，其默认的线程数为宿主机的内核数。<br>  启动并行流式处理虽然简单，只需要将<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">stream()</code>替换成<code style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border-radius: 3px; padding: 2px; font-size: 13px;">parallelStream()</code>即可，但既然是并行，就会涉及到多线程安全问题，所以在启用之前要先确认并行是否值得（并行的效率不一定高于顺序执行），另外就是要保证线程安全。此两项无法保证，那么并行毫无意义，毕竟结果比速度更加重要，以后有时间再来详细分析一下并行流式数据处理的具体实现和最佳实践。</p>
    <hr>
    <p style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; margin-bottom: 16px; color: rgb(61, 70, 77); font-family: &quot;Pingfang SC&quot;, STHeiti, &quot;Lantinghei SC&quot;, &quot;Open Sans&quot;, Arial, &quot;Hiragino Sans GB&quot;, &quot;Microsoft YaHei&quot;, &quot;WenQuanYi Micro Hei&quot;, SimSun, sans-serif; white-space: normal; background-color: rgb(248, 248, 248);">鉴于作者水平有限，文中不免有错误之处，欢迎大家指正～<br>同步更新站点：<a href="http://www.zhenchao.org/" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border: none; outline: 0px; transition: color 0.3s; text-decoration: none; color: rgb(68, 102, 187);">www.zhenchao.org</a><br>书籍推荐：<a href="https://book.douban.com/subject/25912747/" style="box-sizing: inherit; -webkit-tap-highlight-color: transparent; border: none; outline: 0px; transition: color 0.3s; text-decoration: none; color: rgb(68, 102, 187);">Java 8 In Action</a></p>
    <p><br></p>
   </div> 
  </div>  
 </body>
</html>